/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.starter.excel.configuration;

import cn.idev.excel.converters.Converter;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.elsfs.cloud.starter.excel.aop.ResponseExcelReturnValueHandler;
import org.elsfs.cloud.starter.excel.converters.InstantConverter;
import org.elsfs.cloud.starter.excel.converters.LocalDateStringConverter;
import org.elsfs.cloud.starter.excel.converters.LocalDateTimeStringConverter;
import org.elsfs.cloud.starter.excel.converters.LocalTimeStringConverter;
import org.elsfs.cloud.starter.excel.converters.LongStringConverter;
import org.elsfs.cloud.starter.excel.converters.StringArrayConverter;
import org.elsfs.cloud.starter.excel.converters.ZonedDateTimeStringConverter;
import org.elsfs.cloud.starter.excel.enhance.DefaultWriterBuilderEnhancer;
import org.elsfs.cloud.starter.excel.enhance.WriterBuilderEnhancer;
import org.elsfs.cloud.starter.excel.handler.ManySheetWriteHandler;
import org.elsfs.cloud.starter.excel.handler.SheetWriteHandler;
import org.elsfs.cloud.starter.excel.handler.SingleSheetWriteHandler;
import org.elsfs.cloud.starter.excel.head.I18nHeaderCellWriteHandler;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;

/**
 * Excel处理器配置
 *
 * @author zeng
 */
@AutoConfiguration
@RequiredArgsConstructor
public class ExcelHandlerConfiguration {
  private final ExcelConfigProperties configProperties;

  /**
   * 获取所有转换器
   *
   * @return list
   */
  public List<Converter<?>> getConverter() {
    ArrayList<Converter<?>> converters = new ArrayList<>();
    converters.add(InstantConverter.INSTANCE);
    converters.add(LocalDateStringConverter.INSTANCE);
    converters.add(LocalDateTimeStringConverter.INSTANCE);
    converters.add(LocalTimeStringConverter.INSTANCE);
    converters.add(LongStringConverter.INSTANCE);
    converters.add(StringArrayConverter.INSTANCE);
    converters.add(ZonedDateTimeStringConverter.INSTANCE);
    return converters;
  }

  /**
   * ExcelBuild增强
   *
   * @return DefaultWriterBuilderEnhancer 默认什么也不做的增强器
   */
  @Bean
  @ConditionalOnMissingBean
  public WriterBuilderEnhancer writerBuilderEnhancer() {
    return new DefaultWriterBuilderEnhancer();
  }

  /** 单sheet 写入处理器 */
  @Bean
  @ConditionalOnMissingBean
  public SingleSheetWriteHandler singleSheetWriteHandler() {
    return new SingleSheetWriteHandler(configProperties, getConverter(), writerBuilderEnhancer());
  }

  /** 多sheet 写入处理器 */
  @Bean
  @ConditionalOnMissingBean
  public ManySheetWriteHandler manySheetWriteHandler() {
    return new ManySheetWriteHandler(configProperties, getConverter(), writerBuilderEnhancer());
  }

  /**
   * 返回Excel文件的 response 处理器
   *
   * @param sheetWriteHandlerList 页签写入处理器集合
   * @return ResponseExcelReturnValueHandler
   */
  @Bean
  @ConditionalOnMissingBean
  public ResponseExcelReturnValueHandler responseExcelReturnValueHandler(
      List<SheetWriteHandler> sheetWriteHandlerList) {
    return new ResponseExcelReturnValueHandler(sheetWriteHandlerList);
  }

  /**
   * excel 头的国际化处理器
   *
   * @param messageSource 国际化源
   */
  @Bean
  @ConditionalOnBean(MessageSource.class)
  @ConditionalOnMissingBean
  public I18nHeaderCellWriteHandler i18nHeaderCellWriteHandler(MessageSource messageSource) {
    return new I18nHeaderCellWriteHandler(messageSource);
  }
}
